package com.framework.utils.ali;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayFundTransOrderQueryRequest;
import com.alipay.api.request.AlipayFundTransToaccountTransferRequest;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayFundTransOrderQueryResponse;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.framework.entity.aliPay.AliPayConfig;
import com.framework.exception.RRException;
import org.apache.commons.collections.map.HashedMap;

import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 支付宝
 */
public class AliPay {

	public static final String ALI_PAY_TYPE = "alipay";//支付宝
	public static final String ANT_TYPE = "ant";//余额

	public static final String PAYEE_TYPE = "ALIPAY_LOGONID";//支付宝转账类型
    //Map<String,Object> map 是前端传来的参数。解析出来然后放到AlipayTradeAppPayModel里然后在把model对象給request去请求支付宝
    public static String Pay(Map<String,Object> map,AliPayConfig aliPayConfig) {
        String orderStr = "";
        try {
            Map<String, String> orderMap = new LinkedHashMap<>(); // 订单实体
            Map<String, String> bizModel = new LinkedHashMap<>(); // 公共实体
			String body = (String)map.get("body");
			String subject = (String)map.get("subject");
			String order_no = (String)map.get("order_no");
            /****** 2.商品参数封装开始 *****/ // 手机端用
            // 商户订单号，商户网站订单系统中唯一订单号，必填
            orderMap.put("out_trade_no", (String)map.get("order_no"));
            // 订单名称，必填
            orderMap.put("subject", "支付宝支付");
            // 付款金额，必填
			Object amount = map.get("amount");
            String totalAmount = String.valueOf(amount);
            orderMap.put("total_amount",totalAmount );
            // 销售产品码 必填
            orderMap.put("product_code", "QUICK_WAP_PAY");
            /****** --------------- 3.公共参数封装 开始 ------------------------ *****/ // 支付宝用
            // 1.商户appid
            bizModel.put("app_id", aliPayConfig.getAppId());
            // 2.请求网关地址
            bizModel.put("method", aliPayConfig.getGatewayUrl());
            // 3.请求格式
            bizModel.put("format", aliPayConfig.getFormat());
            // 4.回调地址
            bizModel.put("return_url", aliPayConfig.getNotifyUrl());
            // 5.私钥
            bizModel.put("private_key", aliPayConfig.getMerchantPrivateKey());
            // 6.商家id
            bizModel.put("seller_id", aliPayConfig.getSysServiceProviderId());
            // 7.加密格式
            bizModel.put("sign_type", aliPayConfig.getSignType() + "");
            /****** --------------- 3.公共参数封装 结束 ------------------------ *****/
            // 实例化客户端
            AlipayClient client = new DefaultAlipayClient(aliPayConfig.getGatewayUrl(), aliPayConfig.getAppId(),aliPayConfig.getMerchantPrivateKey(), aliPayConfig.getFormat(), aliPayConfig.getCharset(), aliPayConfig.getAliPayPublicKey(),aliPayConfig.getSignType());
            // 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
            AlipayTradeAppPayRequest ali_request = new AlipayTradeAppPayRequest();
            // SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
            // model.setPassbackParams(URLEncoder.encode((String)orderMap.get("body").toString()));;
            // //描述信息 添加附加数据
            model.setBody(body); //商品信息
            model.setSubject(subject); // 商品名称
            model.setOutTradeNo(order_no); // 商户订单号(自动生成)
            model.setTotalAmount(totalAmount); // 支付金额
            model.setProductCode("QUICK_MSECURITY_PAY"); // 销售产品码
			String sellerId = aliPayConfig.getSysServiceProviderId();
            model.setSellerId(sellerId); // 商家id
            ali_request.setBizModel(model);
			String notifyUrl = aliPayConfig.getNotifyUrl();
            ali_request.setNotifyUrl(notifyUrl); // 回调地址
            AlipayTradeAppPayResponse responses = client.sdkExecute(ali_request);
            orderStr = responses.getBody();
            System.out.println(orderStr); // 就是orderString 可以直接给客户端请求，无需再做处理
        } catch (Exception e) {
            e.printStackTrace();
        }
        return orderStr;
    }

	/**
	 * 支付宝转账
	 * @param aliPayConfig 支付宝应用参数
	 * @param orderNo 订单号
	 * @param payeeAccount 支付宝账号
	 * @param payerRealName 支付宝收款账户姓名
	 * @param amount 金额
	 * @param remark 备注说明,用来做区分说明 XX平台提现
	 */
    public static void aLiTransfer(AliPayConfig aliPayConfig,String orderNo,String payeeAccount,String payerRealName,BigDecimal amount,String remark) {
    	Map<String,Object> respMap = new LinkedHashMap<>();
		respMap.put("payee_type",PAYEE_TYPE);
		//订单号
		respMap.put("out_biz_no",orderNo);
		//支付宝账户
		respMap.put("payee_account",payeeAccount);
		//支付宝账户姓名
		respMap.put("payee_real_name",payerRealName);
		//金额
		respMap.put("amount",amount);
		respMap.put("remark",remark);
		String resJson = JSONObject.toJSONString(respMap);
		try {
			AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",aliPayConfig.getAppId(),aliPayConfig.getMerchantPrivateKey(),aliPayConfig.getFormat(),aliPayConfig.getCharset(),aliPayConfig.getAliPayPublicKey(),aliPayConfig.getSignType());
			AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
			request.setBizContent(resJson);
			AlipayFundTransToaccountTransferResponse response = alipayClient.execute(request);
			if(response.isSuccess()){
				System.out.println("===============调用支付宝转账成功==============");
			} else {
				System.out.println("===============调用支付宝转账失败=============="+response.getSubMsg()+"错误码："+response.getSubMsg());
				//余额不足时，换个提示
				if("PAYER_BALANCE_NOT_ENOUGH".equals(response.getSubCode())){
					throw new RRException("9000","当前提现人数较多，请稍后再试");
				}
				throw new RRException("9000",response.getSubMsg()+"错误码："+response.getSubMsg());
			}
		} catch (AlipayApiException e) {
			System.out.println("===============调用支付宝转账异常=============="+e.getMessage());
			throw new RRException("9000","调用支付宝转账异常");
		}
	}

	/**
	 * 支付宝账单转账查询
	 * @param aliPayConfig 支付宝应用参数
	 * @param orderNo 订单单号
	 * @return map格式code和msg
	 */
	public static Map<String,Object> aLiTransferQuery(AliPayConfig aliPayConfig,String orderNo) {
    	Map<String,Object> map = new HashedMap();
		Map<String,Object> respMap = new LinkedHashMap<>();
		//订单号
		respMap.put("out_biz_no",orderNo);
		String resJson = JSONObject.toJSONString(respMap);
		try {
			AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.getGatewayUrl(),aliPayConfig.getAppId(),aliPayConfig.getMerchantPrivateKey(),aliPayConfig.getFormat(),aliPayConfig.getCharset(),aliPayConfig.getAliPayPublicKey(),aliPayConfig.getSignType());
			AlipayFundTransOrderQueryRequest request = new AlipayFundTransOrderQueryRequest();
			request.setBizContent(resJson);
			AlipayFundTransOrderQueryResponse response = alipayClient.execute(request);
			if(response.isSuccess()){
				System.out.println("================查询支付宝转账账单调用成功=============");
				//支付宝订单状态 SUCCESS：成功 FAIL：失败  INIT：等待处理  DEALING：处理中  REFUND：退票 UNKNOWN：未知
				String status = response.getStatus();
				String msg = response.getMsg();
				map.put("code",status);
				map.put("msg",msg);
				return map;
			} else {
				map.put("code","ERROR");
				map.put("msg",response.getErrorCode()+"-"+response.getFailReason());
				System.out.println("================查询支付宝转账账单调用失败============="+response.getErrorCode()+"错误码："+response.getFailReason());
				return map;
			}
		}catch (AlipayApiException e) {
			System.out.println("================查询支付宝转账账单调用异常============="+e.getMessage());
			return  null;
		}
	}
}
